﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Collections.Specialized;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace DataAccess
{
    public partial class DataAccess
    {
        public DataAccessResult GetHostServiceProperty(String SubscriptionID, String CertificatePath,String ServiceName, bool EmbedDetail)
        {
            DataAccessResult result = new DataAccessResult();
            string requestUrl = "https://management.core.windows.net/" + SubscriptionID + "/services/hostedservices/" + ServiceName;
            
            if (EmbedDetail)
            {
                requestUrl += "?embed-detail=true";
            }
            string ReturnBody = string.Empty;
            WebResponse resp = null;
            try
            {
                NameValueCollection RequestHeaders = new NameValueCollection();
                RequestHeaders.Add("x-ms-version", x_ms_version);

                X509Certificate cert = X509Certificate.CreateFromCertFile(CertificatePath);
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
                request.Method = "GET";
                request.ClientCertificates.Add(cert);
                if (RequestHeaders != null)
                {
                    request.Headers.Add(RequestHeaders);
                }


                resp = request.GetResponse();
               


                if (resp != null)
                {

                    using (StreamReader sr = new StreamReader(resp.GetResponseStream(), true))
                    {
                        ReturnBody = sr.ReadToEnd();
                        sr.Close();
                    }
                    if (ReturnBody != null)
                    {
                        Entities.HostedServiceProperty serviceProperty = new Entities.HostedServiceProperty();
                        XElement el = XElement.Parse(ReturnBody);
                        IEnumerable<XElement> allElements = el.Elements();
                        foreach (XElement element in allElements)
                        {
                            string ElementName = element.Name.LocalName.Trim().ToLower();
                            string ElementValue = element.Value;
                            switch (ElementName)
                            {
                                case "url":
                                    serviceProperty.Url = ElementValue;
                                    break;
                                case "servicename":
                                    serviceProperty.ServiceName = ElementValue;
                                    break;
                                case "hostedserviceproperties":
                                    foreach (XElement e1 in element.Elements())
                                    {
                                        string ElementName1 = e1.Name.LocalName.Trim().ToLower();
                                        string ElementValue1 = e1.Value;
                                        switch (ElementName1)
                                        {
                                            case "affinitygroup":
                                                serviceProperty.AffinityGroup = ElementValue1;
                                                break;
                                            case "description":
                                                serviceProperty.Description = ElementValue1;
                                                break;
                                            case "label":
                                                byte[] encodedDataAsBytes = System.Convert.FromBase64String(ElementValue1);
                                                serviceProperty.Label = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes); ;
                                                break;
                                            case "location":
                                                serviceProperty.Location = ElementValue1;
                                                break;
                                        }
                                    }
                                    break;
                                case "deployments":
                                    List<Entities.DeploymentProperty> deploymentList = new List<Entities.DeploymentProperty>();
                                    foreach (XElement e1 in element.Elements())
                                    {
                                        Entities.DeploymentProperty deploymentProperty = new Entities.DeploymentProperty();
                                        foreach (XElement e2 in e1.Elements())
                                        {
                                            string ElementName2 = e2.Name.LocalName.Trim().ToLower();
                                            string ElementValue2 = e2.Value;
                                            switch (ElementName2)
                                            {
                                                case "name":
                                                    deploymentProperty.Name = ElementValue2;
                                                    break;
                                                case "deploymentslot":
                                                    deploymentProperty.DeploymentSlot = ElementValue2;
                                                    break;
                                                case "privateid":
                                                    deploymentProperty.PrivateID = ElementValue2;
                                                    break;
                                                case "label":
                                                    byte[] encodedDataAsBytes = System.Convert.FromBase64String(ElementValue2);
                                                    deploymentProperty.Label = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes); 
                                                    break;
                                                case "status":
                                                    deploymentProperty.Status = ElementValue2;
                                                    break;
                                                case "configuration":
                                                    deploymentProperty.Configuration = ElementValue2;
                                                    break;
                                                case "url":
                                                    deploymentProperty.Url = ElementValue2;
                                                    break;

                                                case "roleinstancelist":
                                                    List<Entities.RoleInstance> roleList = new List<Entities.RoleInstance>();
                                                    foreach (XElement roleInstance in e2.Elements())
                                                    {
                                                        Entities.RoleInstance role = new Entities.RoleInstance();
                                                        foreach (XElement e3  in roleInstance.Elements())
                                                        {
                                                            string ElementName3 = e3.Name.LocalName.Trim().ToLower();
                                                            string ElementValue3 = e3.Value;
                                                            switch (ElementName3)
                                                            {
                                                                case "rolename":
                                                                    role.RoleName = ElementValue3;
                                                                    break;
                                                                case "instancename":
                                                                    role.InstanceName = ElementValue3;
                                                                    break;
                                                                case "instancestatus":
                                                                    role.InstanceState = ElementValue3;
                                                                    break;
                                                            }
                                                        }
                                                        roleList.Add(role);
                                                    }
                                                    deploymentProperty.RoleInstanceList = roleList;
                                                    break;
                                                
                                            }
                                        }
                                        deploymentList.Add(deploymentProperty);
                                    }
                                    serviceProperty.DeploymentPropertyList = deploymentList;
                                    break;
                            }
                        }
                        if (String.IsNullOrEmpty(serviceProperty.ServiceName))
                        {
                            serviceProperty.ServiceName = serviceProperty.Url.Substring(serviceProperty.Url.LastIndexOf('/') + 1);
                        }
                        result.IsOperationSuccessful = true;
                        result.ServiceProperty = serviceProperty;
                    }
                }
            }
            catch (WebException ex)
            {
                result.IsOperationSuccessful = false;
                result.Error = ex;
                result.ServiceProperty = null;
            }
            catch (Exception ex)
            {
                result.IsOperationSuccessful = false;
                result.Error = ex;
                result.ServiceProperty = null;
            }
            finally
            {
                if (resp != null) { resp.Close(); }
                resp = null;
            }
            return result;
        }

        private string getXmlValue(XmlDocument xdoc, string tagName)
        {
            XmlNodeList lst = xdoc.GetElementsByTagName(tagName);
            return lst[0].InnerText;
        }
    }
}
